package com.liachen.stock.ext.impl;

import com.google.common.base.Splitter;
import com.liachen.common.constant.Constant;
import com.liachen.common.util.ToolsUtil;
import com.liachen.stock.ext.NetEaseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class NetEaseServiceImpl implements NetEaseService {
    private static final String ZCFZB_URL = "http://quotes.money.163.com/f10/zcfzb_%s.html?type=year";
    private static final String LRB_URL = "http://quotes.money.163.com/f10/lrb_%s.html?type=year";
    private static final String XJLLB_URL = "http://quotes.money.163.com/f10/xjllb_%s.html?type=year";

    private static final String ORG_FILE_NAME = "财报分析模板.xlsx";

    @Override
    public void exportFinanceData(String codes) {
        List<String> codeList = Splitter.on(",").splitToList(codes);
        codeList.stream().forEach(code -> {
            try {
                FileInputStream file =
                        new FileInputStream(new File(String.format("%s\\%s", Constant.FILE_PATH, ORG_FILE_NAME)));

                XSSFWorkbook workbook = new XSSFWorkbook(file);
                XSSFSheet ZCFZBSheet = workbook.getSheetAt(0);
                XSSFSheet LRBSheet = workbook.getSheetAt(1);
                XSSFSheet XJLLBSheet = workbook.getSheetAt(2);
                XSSFSheet FXSheet = workbook.getSheetAt(3);

                //资产负债表
                Document doc = Jsoup.connect(String.format(ZCFZB_URL, code)).get();
                String stockName = doc.select("body > div.area > div.header > div.stock_info > table > tbody > tr > td.col_1 > h1 > a").text();
                Elements elements = doc.select("#scrollTable > div.col_r > table > tbody > tr");
                convertWorkBook(elements, ZCFZBSheet, workbook);

                //利润表
                doc = Jsoup.connect(String.format(LRB_URL, code)).get();
                elements = doc.select("#scrollTable > div.col_r > table > tbody > tr");
                convertWorkBook(elements, LRBSheet, workbook);

                //现金流量表
                doc = Jsoup.connect(String.format(XJLLB_URL, code)).get();
                elements = doc.select("#scrollTable > div.col_r > table > tbody > tr");
                convertWorkBook(elements, XJLLBSheet, workbook);

                FXSheet.setForceFormulaRecalculation(true);
                file.close();
                String path = String.format("%s\\%s\\年报", Constant.COMPANY_PATH, StringUtils.deleteWhitespace(stockName));
                ToolsUtil.mkdir(path);
                FileOutputStream outFile =
                        new FileOutputStream(new File(String.format("%s\\%s财报分析.xlsx", path, stockName)));
                workbook.write(outFile);
                outFile.close();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                log.error("导出数据失败，code = {}", code);
            }
        });
    }

    private void convertWorkBook(Elements elements, XSSFSheet sheet, XSSFWorkbook workbook) {
        XSSFRow row = null;
        int rowNum = 0;
        for (int i = 0; i < elements.size(); i++) {
            int cellNum = 1;
            if (i == 0) {
                Elements headers = elements.get(i).select("th");
                for (Element header : headers) {
                    row = sheet.getRow(rowNum);
                    removeCell(row, headers);
                    XSSFCell cell = row.getCell(cellNum);
                    if (Objects.isNull(cell)) {
                        cell = row.createCell(cellNum);
                    }
                    cell.setCellValue(header.text());
                    cellNum++;
                }
            } else {
                Elements dataValues = elements.get(i).select("td");

                for (Element data : dataValues) {
                    row = sheet.getRow(rowNum);
                    removeCell(row, dataValues);
                    XSSFCell cell = row.getCell(cellNum);
                    if (Objects.isNull(cell)) {
                        cell = row.createCell(cellNum);
                    }
                    XSSFCellStyle cellStyle = cell.getCellStyle();
                    XSSFFont font = cellStyle.getFont();
                    XSSFDataFormat dataFormat = workbook.createDataFormat();
                    cellStyle.setDataFormat(dataFormat.getFormat("#,##0"));
                    if (StringUtils.isNotEmpty(data.text())) {
                        if ("--".equalsIgnoreCase(data.text())) {
                            cell.setBlank();
                        } else {
                            double dataValue = new Double(data.text().replaceAll(",", ""));
                            font.setColor(Font.COLOR_NORMAL);
                            cellStyle.setFont(font);
                            cell.setCellStyle(cellStyle);
                            cell.setCellValue(dataValue);
                        }

                    }
                    cellNum ++;
                }
            }
            rowNum ++;
        }
    }

    private void removeCell(XSSFRow row, Elements headers) {
        int excelRowNum = row.getLastCellNum();
        if (excelRowNum > headers.size()) {
            for (int j = headers.size(); j < excelRowNum; j++) {
                row.getCell(j).setBlank();
            }
        }
    }



    public static void main(String[] args) {
        NetEaseServiceImpl test = new NetEaseServiceImpl();
        test.exportFinanceData("002394");
    }
}
